﻿using DAL;
using IService;
using Microsoft.Data.SqlClient;
using Model;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using NPOI;
using System.Threading.Tasks;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
// NPOI必要命名空间
using NPOI.SS.UserModel;       // 核心接口（IWorkbook、ISheet等）
using NPOI.XSSF.UserModel;     // 处理.xlsx格式
using NPOI.HSSF.UserModel;     // 处理.xls格式
using NPOI.SS.Util;
using static IService.IGoodsTypeService;
namespace Service
{
    public class GoodsTypeService : IGoodsTypeService
    {
        private GoodsTypeDal _goodsTypeDal = new GoodsTypeDal();

        public GoodsTypeService()
        {
           
        }


        public Task<List<GoodsType>> GetFuzzyGoodsTypes(string typeNameOrCode, int? status, string updateBy, DateTime? startTime, DateTime? endTime)    // 新增：结束时间
        {
            // 调用DAL层的模糊查询方法和查询所有的方法
            return _goodsTypeDal.GetFuzzySearchAsync(
                 typeNameOrCode,
                 status,  // 改为可空类型，支持"不筛选"
                 updateBy,
                 startTime,  // 新增：开始时间
                 endTime    // 新增：结束时间
            );
        }

        public Task<List<GoodsType>> GoodsTypesAdd(string ParentCategoryId, string GoodsTypeCode, string GoodsTypeName, int SortOrder, int Status, string Remarks)
        {
            return _goodsTypeDal.GetAdd(
                ParentCategoryId,
                GoodsTypeCode,
                GoodsTypeName,
                SortOrder,
                Status,
                Remarks
            );
        }
        
        public async Task<int> GoodsTypesDelete(int goodsTypeId)
        {

            return await _goodsTypeDal.UpdateIsDeletedAsync(
                goodsTypeId
            );
        }

        public Task<List<GoodsType>> GoodsTypesUpdate(int GoodsTypeId, string ParentCategoryId, string GoodsTypeCode, string GoodsTypeName, int SortOrder, int Status, string Remarks)
        {
            return _goodsTypeDal.GetFuzzyUpdateAsync(
                GoodsTypeId,
                ParentCategoryId,
                GoodsTypeCode,
                GoodsTypeName,
                SortOrder,
                Status,
                Remarks
            );
        }
        //GoodsTypesAllAsync
        public async Task<List<GoodsType>> GoodsTypesAllAsync()
        {
            return await _goodsTypeDal.GoodsTypesAllAsync();
        }
        private DataTable ParseExcel(Stream stream, string fileExt)
        {
            IWorkbook workbook = null;
            DataTable dt = new DataTable();

            try
            {
                // 根据文件扩展名创建对应的Workbook
                if (fileExt.Equals(".xlsx", StringComparison.OrdinalIgnoreCase))
                {
                    workbook = new XSSFWorkbook(stream);  // 处理Excel 2007+ (.xlsx)
                }
                else if (fileExt.Equals(".xls", StringComparison.OrdinalIgnoreCase))
                {
                    workbook = new HSSFWorkbook(stream);  // 处理Excel 97-2003 (.xls)
                }
                else
                {
                    throw new ArgumentException("不支持的文件格式，仅支持.xls和.xlsx");
                }

                // 获取第一个工作表（默认取第1个）
                ISheet sheet = workbook.GetSheetAt(0);
                if (sheet == null)
                {
                    throw new Exception("Excel中没有工作表");
                }

                // 读取表头（第1行）
                IRow headerRow = sheet.GetRow(0);
                if (headerRow == null)
                {
                    throw new Exception("Excel表头不存在");
                }

                // 创建DataTable的列（根据表头）
                for (int col = 0; col < headerRow.LastCellNum; col++)
                {
                    string columnName = headerRow.GetCell(col)?.ToString() ?? $"Column_{col + 1}";
                    dt.Columns.Add(columnName);
                }

                // 读取数据行（从第2行开始）
                for (int rowIdx = 1; rowIdx <= sheet.LastRowNum; rowIdx++)
                {
                    IRow dataRow = sheet.GetRow(rowIdx);
                    if (dataRow == null) continue;  // 跳过空行

                    DataRow dtRow = dt.NewRow();
                    for (int colIdx = 0; colIdx < headerRow.LastCellNum; colIdx++)
                    {
                        // 获取单元格值（处理不同类型的单元格）
                        ICell cell = dataRow.GetCell(colIdx);
                        dtRow[colIdx] = GetCellValue(cell);
                    }
                    dt.Rows.Add(dtRow);
                }

                return dt;
            }
            finally
            {
                workbook?.Close();  // 释放资源
            }
        }

        /// <summary>
        /// 辅助方法：获取Excel单元格的实际值（处理不同数据类型）
        /// </summary>
        private string GetCellValue(ICell cell)
        {
            if (cell == null)
                return string.Empty;

            switch (cell.CellType)
            {
                case CellType.String:
                    return cell.StringCellValue.Trim();  // 字符串类型
                case CellType.Numeric:
                    // 处理日期类型（Excel中日期以数字存储）
                    if (DateUtil.IsCellDateFormatted(cell))
                        return cell.DateCellValue.ToString("yyyy-MM-dd");
                    else
                        return cell.NumericCellValue.ToString("0");  // 数字类型
                case CellType.Boolean:
                    return cell.BooleanCellValue.ToString();  // 布尔类型
                case CellType.Formula:
                    // 公式单元格取计算结果
                    return cell.CachedFormulaResultType == CellType.String
                        ? cell.StringCellValue.Trim()
                        : cell.NumericCellValue.ToString("0");
                default:
                    return string.Empty;
            }
        }
        /// <summary>
        /// 导入Excel（增强版校验）
        /// </summary>
        public async Task<ImportResult> ImportExcelAsync(Stream stream, string fileExt, string operatorName)
        {

            var result = new ImportResult();
            var validData = new List<GoodsType>();
            var errors = new List<string>();

            try
            {
                // 1. 解析Excel
                var dt = ParseExcel(stream, fileExt);
                if (dt.Rows.Count == 0)
                {
                    result.ErrorMsg = "Excel中没有有效数据";
                    return result;
                }

                // 2. 表头校验（严格匹配）
                var requiredCols = new Dictionary<string, string>
            {
                { "货品类型编号", "goods_type_code" },
                { "货品类型名称", "goods_type_name" },
                { "上级分类ID", "parent_category_id" },
                { "排序", "sort_order" },
                { "状态", "status" }
            };
                foreach (var col in requiredCols)
                {
                    if (!dt.Columns.Contains(col.Key))
                        throw new Exception($"Excel缺少必填列：{col.Key}（对应数据库字段：{col.Value}）");
                }

                // 3. 批量查询已存在的编号（优化性能：减少数据库访问次数）
                var allCodes = dt.Rows.Cast<DataRow>()
                    .Select(row => row["货品类型编号"].ToString().Trim())
                    .Where(code => !string.IsNullOrEmpty(code))
                    .ToList();
                var existCodes = new List<string>();
                if (allCodes.Any())
                {
                    // 一次性查询所有编号是否存在（需在DAL中新增批量查询方法）
                    existCodes = await _goodsTypeDal.GetExistCodesAsync(allCodes);
                }

                // 4. 逐条处理数据
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    int rowNum = i + 2; // 行号（用户视角）
                    var row = dt.Rows[i];
                    var code = row["货品类型编号"].ToString().Trim();

                    // 快速校验
                    if (string.IsNullOrEmpty(code))
                    {
                        errors.Add($"第{rowNum}行：货品类型编号不能为空");
                        continue;
                    }
                    if (existCodes.Contains(code))
                    {
                        errors.Add($"第{rowNum}行：编号【{code}】已存在");
                        continue;
                    }
                    if (string.IsNullOrEmpty(row["货品类型名称"].ToString().Trim()))
                    {
                        errors.Add($"第{rowNum}行：货品类型名称不能为空");
                        continue;
                    }

                    // 转换为实体
                    validData.Add(new GoodsType
                    {
                        GoodsTypeCode = code,
                        GoodsTypeName = row["货品类型名称"].ToString().Trim(),
                        ParentCategoryId = int.TryParse(row["上级分类ID"].ToString(), out int pid) ? pid : 0,
                        SortOrder = int.TryParse(row["排序"].ToString(), out int sort) ? sort : 0,
                        Status = int.TryParse(row["状态"].ToString(), out int status) ? status : 1,
                        Remarks = row["备注"]?.ToString().Trim() ?? ""
                    });
                }

                // 5. 批量插入
                if (validData.Any())
                {
                    await _goodsTypeDal.BatchInsertAsync(validData, operatorName);
                    result.SuccessCount = validData.Count;
                }

                // 6. 结果处理
                result.FailCount = errors.Count;
                result.ErrorMsg = errors.Count > 0 ? string.Join("；", errors) : "无错误";
            }
            catch (Exception ex)
            {
                result.ErrorMsg = $"导入失败：{ex.Message}";
            }

            return result;
        }

        public async Task<PagedResult<GoodsType>> GetPagedGoodsTypes(
    string typeNameOrCode,
    int? status,
    string updateBy,
    DateTime? startTime,
    DateTime? endTime,
    int pageNum,
    int pageSize
)
        {
            try
            {
                int skip = (pageNum - 1) * pageSize;
                // 确保 DAL 方法返回非 null 列表（即使空数据也返回空列表）
                var list = await _goodsTypeDal.GetPagedListAsync(
                    typeNameOrCode, status, updateBy, startTime, endTime, skip, pageSize)
                    ?? new List<GoodsType>(); // 兜底：若 DAL 返回 null，用空列表

                int total = await _goodsTypeDal.GetTotalCountAsync(
                    typeNameOrCode, status, updateBy, startTime, endTime);

                // 强制返回 PagedResult 对象（绝对不为 null）
                return new PagedResult<GoodsType>
                {
                    Total = total,
                    List = list
                };
            }
            catch (Exception ex)
            {
                // 异常时返回空数据的 PagedResult，避免返回 null
                Console.WriteLine($"分页查询异常：{ex.Message}");
                return new PagedResult<GoodsType>
                {
                    Total = 0,
                    List = new List<GoodsType>()
                };
            }
        }
    }
}
